package rs.dalao.syc.user.all.config;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import rs.dalao.syc.common.response.JsonResult;
import rs.dalao.syc.common.response.ServiceCode;
import rs.dalao.syc.user.all.filter.JwtAuthorizationFilter;

import java.io.PrintWriter;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthorizationFilter jwtAuthorizationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //配置Spring Security允许跨域访问
        http.cors();

        // 配置Spring Security不再使用Session
        // 注意：不要使用NEVER，它表示的是“不主动创建Session”，但是，当Session已存在时，仍会使用
        // 推荐使用STATELESS，它表示的是“无状态”，无论是否存在Session都不会使用
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // 将解析JWT的过滤器添加到Spring Security框架的过滤器链中
        http.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);

        // 处理无认证信息却尝试访问需要通过认证的资源时的异常
        http.exceptionHandling().authenticationEntryPoint((request, response, e) -> {
            String message = "当前未登录，或登录信息已过期，请登录！";
            JsonResult jsonResult = JsonResult.fail(ServiceCode.ERROR_UNAUTHORIZED, message);
            String jsonResultString = JSON.toJSONString(jsonResult);
            response.setContentType("application/json; charset=utf-8");
            PrintWriter printWriter = response.getWriter();
            printWriter.println(jsonResultString);
            printWriter.close();
        });

        // 白名单
        // 配置路径时，使用Ant-Style匹配模式：
        // 使用1个星号可以匹配当前层级的任何内容，例如 /user/* 可以匹配 /user/delete、/user/list，但不可以匹配 /user/9527/delete
        // 使用2个星号可以匹配若干层级的任何内容，例如 /user/** 可以匹配 /user/delete、/user/list、/user/9527/delete
        String[] urls = {
                "/doc.html",
                "/**/*.js",
                "/**/*.css",
                "/swagger-resources",
                "/v2/api-docs",
                "/favicon.ico",
                "/user/image/*",
                "/resources/**"
        };

        // 禁用“防止伪造的跨域攻击”的防御机制（CSRF）
        http.csrf().disable();

        // 配置请求授权
        http.authorizeRequests()
                .mvcMatchers(urls).permitAll()
                .anyRequest().authenticated();

        // 是否启用登录表单
        // 如果调用以下方法，则启用，当未通过认证时，会重定向到登录表单
        // 如果未调用以下方法，则禁用，当未通过认证时，会响应403
        // http.formLogin();
    }

}
